/////////////////////////////////////////////////////////////////////////////
// Name:        ax_menu_choice.h
// Purpose:     Modal choice menu class
// Author:      Julian Smart
// Modified by:
// Created:     2009-03-20
// RCS-ID:
// Copyright:   (c) Julian Smart
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#ifndef _AX_MENU_CHOICE_H_
#define _AX_MENU_CHOICE_H_

class AxChoiceMenuItem;

/*
 * Includes
 */

#include "ax/ax_menu.h"
#include "ax/ax_activator.h"
#include "ax/ax_validator.h"
#include "ax/ax_menu_modal.h"
 
/**
    @class AxModalChoiceMenu

    Shows a modal choice menu.

    @category{ax}

 */

class AxModalChoiceMenu: public AxModalMenu
{
    DECLARE_CLASS( AxModalChoiceMenu )

public:
// Constructors

    AxModalChoiceMenu() { Init(); }

    AxModalChoiceMenu(AxMenuController* controller, AxMenuItem* item,
        const wxString& menuLabel,
        const wxString& description,
        const wxArrayString& labels,
        const wxArrayString& ids,
        const wxArrayString& descriptions,
        const wxString& defaultId = wxEmptyString);
    
    ~AxModalChoiceMenu() {}

// Operations

    void Init() {}

protected:

};

/**
    @class AxChoiceMenuActivator

    Activator for a modal choice menu's items.

    @category{ax}

 */

class AxChoiceMenuActivator: public AxActivator
{
public:
    
    DECLARE_DYNAMIC_CLASS( AxChoiceMenuActivator )

public:
// Constructors

    AxChoiceMenuActivator(AxModalChoiceMenu* menu = NULL) { Init(); m_choiceMenu = menu; }
    AxChoiceMenuActivator(const AxChoiceMenuActivator& activator) { Init(); Copy(activator); }

// Operations

    void Init() { m_choiceMenu = NULL; }

    void Copy(const AxChoiceMenuActivator& activator);

    virtual AxActivator* Clone() const { return new AxChoiceMenuActivator(*this); }

    virtual AxMenu* Activate(AxMenuController* controller, AxMenuItem* item);

    AxModalChoiceMenu* GetModalChoiceMenu() const { return m_choiceMenu; }
    void SetModalChoiceMenu(AxModalChoiceMenu* menu) { m_choiceMenu = menu; }

protected:
    AxModalChoiceMenu*        m_choiceMenu;
};

/**
    @class AxChoiceActivator

    Top-level item activator for a modal choice menu item.

    @category{ax}

 */

class AxChoiceActivator: public AxAutoUpdateActivator
{
public:
    
    DECLARE_DYNAMIC_CLASS( AxChoiceActivator )

public:
// Constructors

    AxChoiceActivator() { Init(); }

    AxChoiceActivator(
        const wxString& labelSpec,
        const wxString& descriptionSpec);

    AxChoiceActivator(const AxChoiceActivator& activator) { Init(); Copy(activator); }

    void Init();

    void Copy(const AxChoiceActivator& activator);

    virtual AxActivator* Clone() const { return new AxChoiceActivator(* this); }

    /// Called when the user activates a menu item by pressing return or double-clicking
    virtual AxMenu* Activate(AxMenuController* controller, AxMenuItem* item);

    /// Create menu label or description
    virtual wxString CreateString(const wxString& spec, bool isLabel);

    AxChoiceMenuItem* GetChoiceMenuItem() const;

protected:
};

/**
    @class AxChoiceMenuItem

    This menu item shows a modal choice menu when activated.
    @a label and @a description can both contain the %VALUE% keyword,
    which will be substituted with the current value.

    When the value is changed, a @c wxEVT_COMMAND_CHOICE_SELECTED event
    is generated.

    @category{ax}

 */

class AxChoiceMenuItem: public AxMenuItem
{
    DECLARE_DYNAMIC_CLASS( AxChoiceMenuItem )

public:
// Constructors

    AxChoiceMenuItem(const AxChoiceMenuItem& item) { Copy(item); }
    AxChoiceMenuItem() {}
    AxChoiceMenuItem(const wxString& label, const wxString& description,
        const wxString& id,
        const wxArrayString& labels,
        const wxArrayString& ids,
        const wxArrayString& descriptions,
        int selection = 0);
    bool Create(const wxString& label, const wxString& description,
        const wxString& id,
        const wxArrayString& labels,
        const wxArrayString& ids,
        const wxArrayString& descriptions,
        int selection = 0);

    void Init();

    void Copy(const AxChoiceMenuItem& item);

    virtual AxMenuItem* Clone() const { return new AxChoiceMenuItem(* this); }

    /// Get current selected label
    wxString GetSelectionLabel() const;

    /// Get current selected id
    wxString GetSelectionId() const;

    /// Get current selected index
    int GetSelection() const { return m_selection; }

    /// Set current selection
    virtual void SetSelection(int i);

    /// Set current selection
    virtual void SetSelectionByLabel(const wxString& label);

    /// Set current selection
    virtual void SetSelectionById(const wxString& id);

    /// Create menu label or description
    virtual wxString CreateString(const wxString& spec, bool isLabel);

    void SetLabels(const wxArrayString& labels) { m_labels = labels; }
    const wxArrayString& GetLabels() const { return m_labels; }
    
    void SetIds(const wxArrayString& ids) { m_ids = ids; }
    const wxArrayString& GetIds() const { return m_ids; }
    
    void SetDescriptions(const wxArrayString& descriptions) { m_descriptions = descriptions; }
    const wxArrayString& GetDescriptions() const { return m_descriptions; }

    /// Set menu item label spec, if any
    void SetLabelSpec(const wxString& spec);

    /// Get menu item label spec, if any
    wxString GetLabelSpec() const;

    /// Set menu item description spec, if any
    void SetDescriptionSpec(const wxString& spec);

    /// Get menu item description spec, if any
    wxString GetDescriptionSpec() const;

protected:
    wxArrayString m_labels;
    wxArrayString m_ids;
    wxArrayString m_descriptions;
    int           m_selection;
};

/**
    @class AxChoiceValidator

    Use this with AxChoiceMenuItem to specify a string pointer that
    should be updated to the current value of the menu item.
 */

class AxChoiceValidator: public AxValidator
{
    DECLARE_DYNAMIC_CLASS( AxChoiceValidator )

public:
// Constructors

    AxChoiceValidator(const AxChoiceValidator& validator) { Init(); Copy(validator); }
    AxChoiceValidator(wxString* ptr) { Init(); m_stringPtr = ptr; }
    AxChoiceValidator(int* ptr) { Init(); m_intPtr = ptr; }
    AxChoiceValidator() { Init(); }
    ~AxChoiceValidator() {}

// Operations

    void Copy(const AxChoiceValidator& validator)
    {
        AxValidator::Copy(validator);

        m_stringPtr = validator.m_stringPtr;
        m_intPtr = validator.m_intPtr;
    }

    virtual AxValidator* Clone() const { return new AxChoiceValidator(*this); }

    /// Override to pass a value from the UI to a data structure
    virtual bool TransferDataFromMenu();

    /// Override to pass a value from a data structure to the UI
    virtual bool TransferDataToMenu();

    /// Initialize variables
    void Init() { m_stringPtr = NULL; m_intPtr = NULL; }

protected:
    wxString*   m_stringPtr;
    int*        m_intPtr;
};


#endif
    // _AX_MENU_CHOICE_H_
